﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Wiggle
{
    public partial class WiggleForm : Form
    {
        public WiggleForm(World world)
        {
            this.InitializeComponent();

            this.world = world;
        }
        World world;

        private Bitmap DrawBoardImage()
        {
            const int SCALE = 5;
            Bitmap bitmap = new Bitmap(SCALE * this.world.Board.Size.X, SCALE * this.world.Board.Size.Y);
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                g.FillRectangle(new SolidBrush(Color.White), 0, 0, bitmap.Width, bitmap.Height);

                foreach (KeyValuePair<Cell, Point> pair in this.world.Board.EnumerateItems())
                {
                    Cell cell = pair.Key;
                    Point pt = pair.Value;

                    Color color = cell.Color;
                    // color = Color.FromArgb(64, color);
                    g.FillRectangle(new SolidBrush(color), SCALE * pt.X, SCALE * pt.Y, SCALE, SCALE);
                }
            }

            return bitmap;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.pictureBox1.Image = this.DrawBoardImage();
            this.pictureBox1.ClientSize = this.pictureBox1.Image.Size;

            this.ClientSize = (Size) this.pictureBox1.Location + this.pictureBox1.Size;

            this.Visible = true;
            this.Animate();
        }

        private void Animate()
        {
            while (this.chkRun.Checked)
            {
                if (this.world.Advance() % 1 == 0)
                {
                    Bitmap bitmap = this.DrawBoardImage();
                    this.pictureBox1.Image = (Bitmap) bitmap;

                    if (this.chkVideo.Checked)
                    {
                        if (this.aviMgr == null)
                            this.aviMgr = new AviFile.AviManager("Wiggle.avi", false);

                        bitmap = (Bitmap) bitmap.Clone();
                        if (this.aviStream == null)
                        {
                            AviFile.Avi.AVICOMPRESSOPTIONS opts = new AviFile.Avi.AVICOMPRESSOPTIONS();
                            opts.fccType = (UInt32) AviFile.Avi.mmioStringToFOURCC("vids", 0);
                            opts.fccHandler = (UInt32) AviFile.Avi.mmioStringToFOURCC("cvid", 0);
                            opts.dwKeyFrameEvery = 0;
                            opts.dwQuality = 0;  // 0 .. 10000
                            opts.dwFlags = 0;  // AVICOMRPESSF_KEYFRAMES = 4
                            opts.dwBytesPerSecond = 0;
                            opts.lpFormat = new IntPtr(0);
                            opts.cbFormat = 0;
                            opts.lpParms = new IntPtr(0);
                            opts.cbParms = 0;
                            opts.dwInterleaveEvery = 0;

                            this.aviStream = this.aviMgr.AddVideoStream(opts, 24, bitmap);
                        }
                        else
                            this.aviStream.AddFrame(bitmap);
                    }
                }
                Application.DoEvents();
            }
        }
        AviFile.AviManager aviMgr = null;
        AviFile.VideoStream aviStream = null; 

        protected override void OnClosed(EventArgs e)
        {
            this.chkRun.Checked = false;
            if (this.aviMgr != null)
                this.aviMgr.Close();
        }

        private void chkRun_CheckedChanged(object sender, EventArgs e)
        {
            this.Animate();
        }
    }
}
